package com.laity.demo2;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author: Laity
 * @Project: JavaLaity
 * @Package: com.laity.demo2.Communication03
 * @Date: 2023年11月22日 22:19
 * @Description: 基于JUC的Condition实现精准的通知和唤醒线程
 * 需求 t1执行完，执行t2，t2执行完，执行t3，t3执行完，执行t4,t4执行完 调用t1
 */

public class Communication03 {
    static Thread t1 = null, t2 = null, t3 = null, t4 = null;
    public static void main(String[] args) {
        DataService data = new DataService();
        t1 = new Thread(data::printA, "t1");

        t2 = new Thread(data::printB, "t2");

        t3 = new Thread(data::printC, "t3");

        t4 = new Thread(data::printD, "t4");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

// 唯一资源类
class DataService {
    // 使用JUC创建锁
    private final Lock lock = new ReentrantLock();
    // 监视器
    private final Condition condition1 = lock.newCondition();
    private final Condition condition2 = lock.newCondition();
    private final Condition condition3 = lock.newCondition();
    private final Condition condition4 = lock.newCondition();

    // 模拟一个标识位
    private int number = 1; // 1-t1;2-t2;3-t3;4-t4

    public void printA(){
        lock.lock();
        try {
            // 业务代码 : while条件判断 -> 程序执行 -> 通知唤醒
            while (number!=1) {
                condition1.await();
            }
            System.out.println(Thread.currentThread().getName() + " - number == 1");
            number = 2;
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void printB(){
        lock.lock();
        try {
            // 业务代码 : while条件判断 -> 程序执行 -> 通知
            while (number!=2) {
                condition2.await();
            }
            System.out.println(Thread.currentThread().getName() + " - number == 2");
            number = 3;
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void printC(){
        lock.lock();
        try {
            // 业务代码 : while条件判断 -> 程序执行 -> 通知
            while (number!=3) {
                condition3.await();
            }
            System.out.println(Thread.currentThread().getName() + " - number == 3");
            number = 4;
            condition4.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
    public void printD(){
        lock.lock();
        try {
            // 业务代码 : while条件判断 -> 程序执行 -> 通知
            while (number!=4) {
                condition4.await();
            }
            System.out.println(Thread.currentThread().getName() + " - number == 4");
            number = 1;
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
